package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"strconv"

	"os"
	"strings"
)

/*
学生信息系统添加，无限次数添加和查询，按q退出
1.添加学生信息

	判断此用户有没有添加过
	没有这个用户，就提示输入学生信息(姓名、年龄、性别、住址)

2.查询学生信息

	按名字查询
*/

type Student struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Sex     string `json:"sex"`
	Address string `json:"address"`
}

func main() {
	//fmt.Printf("%T", file)
	//获取文件中json格式的学生信息，并转为map格式
	//file, e := os.OpenFile("student_info.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	file, e := os.OpenFile("student_info.txt", os.O_RDWR|os.O_CREATE, 0666)
	if e != nil {
		fmt.Println("打开文件失败！", e)
		return
	}
	students_info := get_info(file)
	file.Close()
	//获取用户输入
	reader := bufio.NewReader(os.Stdin)
	fmt.Println("-----学生信息系统-----")
	fmt.Println("以下为功能选择")
	fmt.Println("1.添加学生信息")
	fmt.Println("2.查询学生信息")
	fmt.Println("按q/Q退出")
	for {

		fmt.Println("请输入你的选择:")
		input, err := reader.ReadString('\n')
		input = strings.TrimSpace(input)
		if err != nil {
			fmt.Println("读取输入时出错！")
			continue
		}
		if input == "q" || input == "Q" {
			add_to_file(students_info)
			fmt.Println("已退出学生信息系统")
			break
		} else if input == "1" {
			fmt.Println("-----添加学生-----")
			fmt.Println("请输入学生姓名")
			name, err := reader.ReadString('\n')
			name = strings.TrimSpace(name)
			if err != nil {
				fmt.Println("读取输入时出错！")
				continue
			}
			if len(name) == 0 {
				fmt.Println("请正确输入")
				continue
			}
			//判断学生存不存在
			_, ok := students_info[name]
			if ok {
				fmt.Printf("学生%v已存在\n", name)
			} else {
				add_student(file, name, students_info)
			}
		} else if input == "2" {
			fmt.Println("请输入要查询的学生姓名")
			stu_name, err := reader.ReadString('\n')
			stu_name = strings.TrimSpace(stu_name)
			if err != nil {
				fmt.Println("读取输入时出错！", err)
				continue
			}
			stu_info_search(stu_name, students_info)
		} else {
			fmt.Println("请按规则输入！")
			continue
		}
	}
}

func get_info(file *os.File) map[string]map[string]string {
	students_info := make(map[string]map[string]string)

	// 获取当前行的文本
	data, err := ioutil.ReadAll(file)
	if err != nil {
		fmt.Println("获取失败")
	}
	// 创建一个map用于存储解析后的JSON数据
	var student map[string]map[string]interface{}
	// 解析JSON
	err = json.Unmarshal([]byte(data), &student)
	if err != nil {
		fmt.Println("Error parsing JSON:", err)
	}

	for key, value := range student {
		//创建一个新的map来存储学生的属性和值
		studentDate := make(map[string]string)
		// 这里简单地将所有值转换为string类型，但请注意这可能会丢失精度（如数字）
		for k, v := range value {
			studentDate[k] = v.(string)
		}
		students_info[key] = studentDate
	}
	return students_info
}
func stu_info_search(stu_name string, students_info map[string]map[string]string) {
	value, ok := students_info[stu_name]
	if ok {
		fmt.Println("学生信息如下:")
		fmt.Println("姓名:", stu_name)
		fmt.Println("年龄:", value["age"])
		fmt.Println("性别:", value["sex"])
		fmt.Println("住址:", value["address"])
	} else {
		fmt.Println("学生不存在")
	}
}
func add_student(file *os.File, name string, students_info map[string]map[string]string) {
	fmt.Println("请输入学生信息")
	var sex, address string
	//获得性别
	fmt.Print("性别(male/female):")
	if _, err := fmt.Scanln(&sex); err != nil {
		fmt.Println("输入错误,请输入male/female")
		return
	}
	if sex != "male" && sex != "female" {
		fmt.Println("输入错误,请输入male/female")
		return
	}

	//获得年龄
	fmt.Print("年龄:")
	var ageStr string
	if _, err := fmt.Scanln(&ageStr); err != nil {
		fmt.Println("年龄输入错误，应为数字")
		return
	}
	age, err := strconv.Atoi(ageStr) // 将字符串转换为整数
	if err != nil {
		fmt.Println("年龄输入错误，应为数字")
		return
	}

	//获得住址
	fmt.Print("住址:")
	if _, err := fmt.Scanln(&address); err != nil {
		fmt.Println("输入错误,请正确输入")
		return
	}

	//创建一个Student实例
	//student := Student{Name: name, Age: age, Sex: sex, Address: address}
	students_info[name] = map[string]string{
		"age":     strconv.Itoa(age),
		"sex":     sex,
		"address": address,
	}

}
func add_to_file(students_info map[string]map[string]string) {
	file, e := os.OpenFile("student_info.txt", os.O_RDWR|os.O_TRUNC, 0666)
	if e != nil {
		fmt.Println("打开文件失败！", e)
		return
	}
	defer file.Close()
	// 将Person实例编码为JSON格式
	json_data, err := json.Marshal(students_info) // 使用缩进使JSON更易于阅读
	if err != nil {
		fmt.Println("Error encoding JSON:", err)
		return
	}
	//stu_data := json.du
	//_, err = file.WriteString("\n")
	//if err != nil {
	//	fmt.Println("新增学生失败")
	//}

	_, err = io.WriteString(file, string(json_data))
	if err != nil {
		fmt.Println("新增学生失败")
	} else {
		fmt.Println("新增学生成功")
	}
}
